#!/usr/bin/env python

# Import some base Python libraries.
import time
import sys
import logging
import parser
import threading
import SocketServer

# Add the parent directory to the path so that we can qualify
# our hsvo specific libraries with a prefix; this helps avoid
# namespace conflicts with any other libraries, including Python's.
sys.path.append('..')

# Import the stomp library
import hsvo.stomp as stomp

# Import HSVO-specific libraries
from SharedMappingList import SharedMappingList
from HSVOMessageListener import HSVOMessageListener
from HSVODeviceMessageHandler import HSVODeviceMessageHandler

# Import some deployment-specific constants.
from hsvo.constants import SAVOIR_ENDPOINT, SERVICE_ID, OL_ROOT_URL, BI_HOSTNAME, BI_PORT

# Setup logging to stream to standard out.
logging.basicConfig(stream=sys.stdout)

# Display a splash screen to signify the start of the bus interface.
sys.stdout.write(r'''
##########################################
#                                        #
#        HSVO Bus Interface v1.0         # 
#                                        #
##########################################

''')

# If both a hostname and port are specified, instantiate a TCP server.
if BI_HOSTNAME and BI_PORT:
    # Create a threaded TCP server using multiple inheritance
    class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
        pass
    
    # Declare a startDelay variable that will dictate how long we wait before re-attempting
    # TCP server initialization. It will increase on each retry, up to a max of 10.
    startDelay = 0
    # Iterate over this block repeatedly until it succeeds and a break is issued.
    while True:
        # Increment the delay between start attempts, to a maximum of 10.
        if(startDelay < 10):
            startDelay += 2
        try:
            # Instantiate the server using the custom threaded class we've
            # created and the RSO message handler class defined in this package.
            rso = ThreadedTCPServer((BI_HOSTNAME, BI_PORT), HSVODeviceMessageHandler)
            
            # Setup the thread to run the RSO server's main blocking method.
            rso_thread = threading.Thread(target=rso.serve_forever)
            rso_thread.setDaemon(True)
            rso_thread.start()
            
            print "TCP event notification server started."
            break
        except:
            print "Unable to start the TCP event notification server; the port is likely already in use."
            print "Re-attempting start in %d seconds." % (startDelay,)
            time.sleep(startDelay)

# Instantiate the STOMP connector object using the ActiveMQ IP/port.
conn = stomp.Connection(host_and_ports=[('198.164.40.210', 42014)])

# Specify a callback function for the STOMP connection.
conn.set_listener('', HSVOMessageListener())

# Establish the connection and subscribe to the topic.
conn.start()
conn.connect()
conn.subscribe(destination='/topic/'+SERVICE_ID, ack='auto')

# Provide a CLI that accepts commands from the admin.
while True:
    
    # Await user input.
    command = raw_input("")
    
    # Handle a fixed set of command issued by the user.
    if command == 'quit' or command == 'exit':
        if conn.is_connected():
            conn.disconnect()
        rso.shutdown()
        rso_thread.join(10)
        sys.exit(0)
    elif command == 'clear':
        for x in range(100):
            print ""
    elif command == 'disconnect':
        if conn.is_connected():
            conn.disconnect()
    elif command == 'connect':
        if not conn.is_connected():
            conn.connect()
    elif command == 'status':
        if conn.is_connected():
            print 'The ActiveMQ connection is alive.'
        else:
            print 'The ActiveMQ connection is dead.'